 /***************************************************************************
 *   Copyright (C) 2010 by ZhangShine , All Rights Reserved                                  
 *   zhangshine0125@gmail.com                                              
 *                                                                         
 *   This program is free software; you can redistribute it and/or modify  
 *   it under the terms of the GNU General Public License as published by  
 *   the Free Software Foundation; either version 2 of the License, or     
 *   (at your option) any later version.                                   
 *                                                                         
 *   This program is distributed in the hope that it will be useful,       
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         
 *   GNU General Public License for more details.                          
 *                                                                         
 *   You should have received a copy of the GNU General Public License     
 *   along with this program; if not, write to the                         
 *   Free Software Foundation, Inc.,                                       
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             
 ***************************************************************************/

#include "sinaweibo.h"
#include "http.h"
#include "sinaparserxml.h"
#include "sinaservices.h"
#include "configuration.h"
#include <QtNetwork>
#include <QMessageBox>
#include <QByteArray>

/*! \brief SinaWeibo类的构造函数
 *  \param [in] account 指向Account类的指针
 *  
 */
SinaWeibo::SinaWeibo(Account *account)
{
    this->account = account;
    /* Basic Auth*/
    QString concatenated = account->getUsername() + ":" +account->getPassword() ;
    QByteArray data = concatenated.toLocal8Bit().toBase64();
    this->basicAuthInfo = "Basic " + data;
    servicesInstance = SinaServices::getInstance();
    conf = Configuration::getInstance();
    
    this->contentFrame = "<div id=contents> <ul> %1</ul> </div>";
}

SinaWeibo::~SinaWeibo()
{
    //qDebug("sinaweibo deleting");
}

/*! \brief 验证当前用户身份是否合法
 * 
 *  API: http://open.t.sina.com.cn/wiki/index.php/Account/verify_credentials
 *  \return 成功返回true并初始化account中相关内容，反之返回false
 */
bool SinaWeibo::verifyCredentials()
{
    QUrl url;
    url.setUrl(servicesInstance->getServices("VerifyCredentials"));
    QNetworkRequest request;
    request.setUrl(url);
    QMap<QString,QString> params;
    this->setOAuthAuthorize( request, OAuth::GET, servicesInstance->getServices("VerifyCredentials"),params );
    Http *http = new Http(this);
    QString content = http->get(request);
    if(http->hasNetworkError())
    {
        switch(http->getNetworkErrorCode())
        {
        case QNetworkReply::HostNotFoundError: /* Host not found error */
            QMessageBox::information(NULL, tr("网络错误"), tr("请确定已连接网络!"),\
                                     QMessageBox::Yes, QMessageBox::Yes);
            break;
        case QNetworkReply::TimeoutError: /* Timeout error */
            QMessageBox::information(NULL, tr("网络错误"), tr("网络超时!"),\
                                     QMessageBox::Yes, QMessageBox::Yes);
            break;
        case QNetworkReply::AuthenticationRequiredError: /* Login error */
            QMessageBox::information(NULL, tr("网络错误"), tr("用户名或密码错误!"),\
                                     QMessageBox::Yes, QMessageBox::Yes);
            break;
        }
        return false;
    }
    delete http;
    SinaParserXml xml;
    return xml.parserSinaAccountInformation(account, content);
}

/*! \brief 获取当前用户的收藏列表
 * 
 *  新浪API地址: http://open.t.sina.com.cn/wiki/index.php/Favorites
 *  \param [in] page 页码，每页默认20条无法更改
 *  \return 成功返回xml格式的收藏列表，反之返回QString::null
 */
QString SinaWeibo::getFavorites(int page)
{
    QMap<QString,QString> params;
    QString urlString(servicesInstance->getServices("Favorites"));
    QUrl url;
    url.setUrl(urlString);
    QNetworkRequest request;
    if(page>1)
    {
        url.addQueryItem("page", QString::number(page));
        params.insert("page", QString::number(page));
    }
    request.setUrl(url);
    this->setOAuthAuthorize( request, OAuth::GET, servicesInstance->getServices("Favorites"), params);
    Http *http = new Http(this);
    QString content = http->get(request);
    if(http->hasNetworkError())
    {
        return QString::null;
    }
    delete http;
    return content;
}

/*! \brief 根据微博消息ID返回某条微博消息的评论列表
 *
 * API: http://open.t.sina.com.cn/wiki/index.php/Statuses/comments
 * \param [in] id 要获取的评论列表所属的微博消息ID
 * \param [in] page 评论列表的页码
 * \param [in] count 每页评论条数
 * \return 成功返回xml格式的评论列表,反之返回QString::null
 */
QString SinaWeibo::getCommentsList(QString id, int page, int count)
{
    QMap<QString,QString> params;
    QString urlString(servicesInstance->getServices("Comments"));
    QUrl url(urlString);
    if(!id.isEmpty())
    {
        params.insert("id", id);
        url.addQueryItem("id", id);
    }
    if(page>1)
    {
        params.insert("page", QString::number(page));
        url.addQueryItem("page", QString::number(page));
    }
    if(count>0&&count!=20)
    {
        params.insert("count", QString::number(count));
        url.addQueryItem("count", QString::number(count));
    }
    
    QNetworkRequest request(url);
    this->setOAuthAuthorize( request, OAuth::GET, servicesInstance->getServices("Comments"), params);
    Http *http = new Http(this);
    QString xmlContent = http->get(request);
    if(http->hasNetworkError())
    {
        qDebug("error code is %d", http->getNetworkErrorCode());
        return QString::null;
    }
    delete http;
    return xmlContent;
}

QString SinaWeibo::favoritePageStatusToHtml(const QList<Status> &statusList, 
                                            const QMap<QString, Status> &retwStatusMap)
{
    QString zfwb = "转发微博";
    QByteArray zfwbba = zfwb.toAscii().toBase64();
    /*
     %1--------------id
     %2--------------userinfo html
     %3--------------username
     %4--------------tool html
     %5--------------text
     %6--------------ret or picture html
     */
    QString statusHtml="<li><div  id=%1><div class=userinfo>%2</div>"
                       "<div class=weibocontent>%3<div name=%1_tool class=tool>%4</div><p>%5</p>"
                       "<div name=%1_commentArea class=commentArea></div>%6<p>%7</p></div>"
                       "<div class=clear></div></div></li>";
    /*
     1------------retwStatus username
     2------------retwTool html
     3------------retwStatus text
     4------------picture html
     5-----------retwStatus id
     */
    QString retwHtml="<div class=retw>%1<div name=%5_tool class=tool>%2</div><p>%3</p>"
                     "<div name=%5_commentArea class=commentArea></div>%4</div>";
    QString tmp;
    if(statusList.isEmpty())
        return tr("没有更多收藏了!");
    for(int i=0; i<statusList.length(); i++)
    {
        Status status = statusList.at(i);
        QString userinfoHtml="<img width=50 height=50 src="+status.getUserProfileImageUrl()+"></img>";
        QString toolHtml="<a name="+status.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+status.getId()
                         +"\",\""+zfwbba+"\""+ ")>转发</a>"
                         "|<a title=取消收藏 href=javascript:void(0) onclick=deleteFavorite("+status.getId()+")>取消收藏</a>"
                         "|<a title=评论 href=javascript:void(0) onclick=comment("+status.getId()+")>评论</a>";
        QString retwOrPic;
        if(!status.getRetweetedId().isEmpty())
        {
            QString aText = "//@"+status.getUserName()+":"+status.getText();
            toolHtml="<a name="+status.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+status.getId()+"\",\""+
                     aText.toAscii().toBase64()+ "\")>转发</a>"
                     "|<a title=取消收藏 href=javascript:void(0) onclick=deleteFavorite("+status.getId()+")>取消收藏</a>"
                     "|<a title=评论 href=javascript:void(0) onclick=comment("+status.getId()+")>评论</a>";
            Status retwStatus = retwStatusMap.value(status.getRetweetedId());
            QString retwToolHtml = "<a name="+retwStatus.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+
                                   retwStatus.getId()+"\",\""+zfwbba+"\""+ ")>转发</a>"
                          "|<a title=收藏 href=javascript:void(0) onclick=addFavorite("+retwStatus.getId()+")>收藏</a>"
                          "|<a title=评论 href=javascript:void(0) onclick=comment("+retwStatus.getId()+")>评论</a>";
            if(!retwStatus.getThumbnailPic().isEmpty())
                retwOrPic = retwHtml
                            .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+retwStatus.getUserName()+"\",1)>"+
                                 retwStatus.getUserName()+"</a>:")
                            .arg(retwToolHtml)
                            .arg(statusTextFormat(retwStatus.getText()))
                            .arg("<p><img title=点击查看大图 onclick=bigPicture(\""+retwStatus.getOriginalPic()+"\",\""+
                                 retwStatus.getBmiddlePic()+"\") src="+
                                 retwStatus.getThumbnailPic()+" /></p>")
                            .arg(retwStatus.getId());
            else
                retwOrPic = retwHtml
                            .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+retwStatus.getUserName()+"\",1)>"+
                                 retwStatus.getUserName()+"</a>:")
                            .arg(retwToolHtml)
                            .arg(statusTextFormat(retwStatus.getText()))
                            .arg("")
                            .arg(retwStatus.getId());
            //qDebug(toolHtml.toAscii());
        }
        else if(!status.getThumbnailPic().isEmpty())
        {
            retwOrPic = "<p><img title=点击查看大图 onclick=bigPicture(\""+status.getOriginalPic()+"\",\""+
                        status.getBmiddlePic()+"\") src="
                        +status.getThumbnailPic()+"/></p>";
        }
        else
        {
            retwOrPic = "";
        }
        tmp.append(statusHtml
                   .arg(status.getId())
                   .arg(userinfoHtml)
                   .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+status.getUserName()+"\",1)>"+
                        status.getUserName()+"</a>:")
                   .arg(toolHtml)
                   .arg(statusTextFormat(status.getText()))
                   .arg(retwOrPic)
                   .arg(timeFormatHtml(status.getCreatedAt()))
                   );
    }
    
    return contentFrame.arg(tmp);
}

/*! \brief 获得最新At到自己的微博消息
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/mentions
 *  \return 成功返回提到我的微博列表(xml形式), 反之返回QString::null
 */
QString SinaWeibo::getMentions(qint64 sinceId, qint64 maxId, int count, int page)
{
    QMap<QString,QString> params;
    QUrl url;
    QString urlString( servicesInstance->getServices("Mentions"));
    url.setUrl(urlString);
    if( sinceId>0 )
    {
        params.insert("since_id", QString::number(sinceId));
        url.addQueryItem("since_id", QString::number(sinceId));
    }
    if( maxId>0 )
    {
        params.insert("max_id", QString::number(maxId));
        url.addQueryItem("max_id", QString::number(maxId));
    }
    if( count>0 && count!=20 )
    {
        params.insert("count", QString::number(count));
        url.addQueryItem("count", QString::number(count));
    }
    if( page>1 )
    {
        params.insert("page", QString::number(page));
        url.addQueryItem("page", QString::number(page));
    }
    
    QNetworkRequest request;
    request.setUrl(url);
    this->setOAuthAuthorize( request, OAuth::GET, servicesInstance->getServices("Mentions"), params);
    Http *http = new Http(this);
    QString content = http->get(request);
    if(http->hasNetworkError())
    {
        return QString::null;
    }
    delete http;
    return content;//basicHtml.arg(atMePageStatusToHtml(account->atMePageStatus, account->atMePageRetweeted)); 
}

QString SinaWeibo::atMePageStatusToHtml(const QList<Status> &statusList, 
                                        const QMap<QString, Status> &retwStatusMap)
{
    QString zfwb = "转发微博";
    QByteArray zfwbba = zfwb.toAscii().toBase64();
    /*
     %1--------------userinfo html
     %2--------------username
     %3--------------tool html
     %4--------------text
     %5--------------ret or picture html
     %6--------------date time
     %7--------------status id
     */
    QString statusHtml="<li><div class=userinfo>%1</div>"
                       "<div class=weibocontent>%2<div name=%7_tool class=tool>%3</div><p>%4</p>"
                       "<div name=%7_commentArea class=commentArea></div>%5<p>%6</p></div>"
                       "<div class=clear></div></li>";
    /*
     1------------retwStatus username
     2------------retwTool html
     3------------retwStatus text
     4------------picture html
     5------------retwStatus id
     */
    QString retwHtml="<div class=retw>%1<div name=%5_tool class=tool>%2</div><p>%3</p>"
                     "<div name=%5_commentArea class=commentArea></div>%4</div>";
    QString tmp;
    if(statusList.isEmpty())
        return tr("没有更多内容了哦!");
    for(int i=0; i<statusList.length(); i++)
    {
        Status status = statusList.at(i);
        QString userinfoHtml="<img width=50 height=50 src="+status.getUserProfileImageUrl()+"></img>";
        QString toolHtml="<a name="+status.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+status.getId()+"\",\""+
                         zfwbba+"\""+ ")>转发</a>"
                         "|<a title=收藏 href=javascript:void(0) onclick=addFavorite("+status.getId()+")>收藏</a>"
                         "|<a title=评论 href=javascript:void(0) onclick=comment("+status.getId()+")>评论</a>";
        QString retwOrPic;
        if(!status.getRetweetedId().isEmpty())
        {
            QString aText = "//@"+status.getUserName()+":"+status.getText();
            toolHtml="<a name="+status.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+status.getId()+"\",\""+
                     aText.toAscii().toBase64()+ "\")>转发</a>"
                     "|<a title=收藏 href=javascript:void(0) onclick=addFavorite("+status.getId()+")>收藏</a>"
                     "|<a title=评论 href=javascript:void(0) onclick=comment("+status.getId()+")>评论</a>";
            Status retwStatus = retwStatusMap.value(status.getRetweetedId());
            QString retwToolHtml = "<a name="+retwStatus.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+
                                   retwStatus.getId()+"\",\""+zfwbba+"\""+ ")>转发</a>"
                          "|<a title=收藏 href=javascript:void(0) onclick=addFavorite("+retwStatus.getId()+")>收藏</a>"
                          "|<a title=评论 href=javascript:void(0) onclick=comment("+retwStatus.getId()+")>评论</a>";
            if(!retwStatus.getThumbnailPic().isEmpty())
                retwOrPic = retwHtml
                            .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+retwStatus.getUserName()+"\",1)>"+
                                 retwStatus.getUserName()+"</a>:")
                            .arg(retwToolHtml)
                            .arg(statusTextFormat(retwStatus.getText()))
                            .arg("<p><img title=点击查看大图 onclick=bigPicture(\""+retwStatus.getOriginalPic()+"\",\""+
                                 retwStatus.getBmiddlePic()+"\") src="+
                                 retwStatus.getThumbnailPic()+" /></p>")
                            .arg(retwStatus.getId());
            else
                retwOrPic = retwHtml
                            .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+retwStatus.getUserName()+"\",1)>"+
                                 retwStatus.getUserName()+"</a>:")
                            .arg(retwToolHtml)
                            .arg(statusTextFormat(retwStatus.getText()))
                            .arg("")
                            .arg(retwStatus.getId());
            //qDebug(toolHtml.toAscii());
        }
        else if(!status.getThumbnailPic().isEmpty())
        {
            retwOrPic = "<p><img title=点击查看大图 onclick=bigPicture(\""+status.getOriginalPic()+"\",\""+status.getBmiddlePic()
                        +"\") src="+status.getThumbnailPic()+"/></p>";
        }
        else
        {
            retwOrPic = "";
        }
        tmp.append(statusHtml
                   .arg(userinfoHtml)
                   .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+status.getUserName()+"\",1)>"+
                        status.getUserName()+"</a>:")
                   .arg(toolHtml)
                   .arg(statusTextFormat(status.getText()))
                   .arg(retwOrPic)
                   .arg(timeFormatHtml(status.getCreatedAt()))
                   .arg(status.getId())
                   );
    }
    //qDebug(tmp.toAscii());
    return contentFrame.arg(tmp);
}

/*! \brief 根据id获取用户发布的微博消息列表
 *
 *API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/user_timeline
 *  
 * \return 成功则返回微博消息列表(xml格式)，反之返回QString::null
 */
QString SinaWeibo::getUserTimeline(qint64 userId, int count, int page, int baseApp, int feature)
{
    QUrl url;
    QString urlString, servicesString;
    QMap<QString,QString> params;
    if(userId==0||this->account->getId()==QString::number(userId))
    {
        servicesString = servicesInstance->getServices("MyTimeline");
        urlString.append(servicesString);
    }
    else
    {
        servicesString = servicesInstance->getServices("OtherTimeline").arg(userId);
        urlString.append(servicesString);
    }
    url.setUrl(urlString);  
    if(count>0&&count!=20)
    {
        params.insert("count", QString::number(count));
        url.addQueryItem("count", QString::number(count));
    }
    if(page>1)
    {
        params.insert("page", QString::number(page));
        url.addQueryItem("page", QString::number(page));
    }
    if(baseApp==1)
    {
        params.insert("base_app", QString::number(baseApp));
        url.addQueryItem("base_app", QString::number(baseApp));
    }
    if(feature>0&&feature<5)
    {
        params.insert("feature", QString::number(feature));
        url.addQueryItem("feature", QString::number(feature));
    }
    QNetworkRequest request;
    request.setUrl(url);
    this->setOAuthAuthorize( request, OAuth::GET, servicesString, params);
    Http *http = new Http(this);
    QString content = http->get(request);
    if(http->hasNetworkError())
    {
        return QString::null;
    }
    delete http;
    return content;
}

/*! \brief 根据用户昵称来获取发布的微博消息列表
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/user_timeline
 *  \return 成功则返回微博消息列表(xml格式)，反之返回QString::null
 */
QString SinaWeibo::getUserTimelineByScreenName(QString screenName, int count, int page, int baseApp, int feature)
{
    QUrl url;
    QString urlString;
    QMap<QString, QString> params;
    urlString.append(servicesInstance->getServices("MyTimeline"));
    url.setUrl(urlString);
    
    params.insert("screen_name", screenName.toAscii().toPercentEncoding());
    url.addQueryItem("screen_name", screenName.toUtf8());
    
    if(count>0&&count!=20)
    {
        params.insert("count", QString::number(count));
        url.addQueryItem("count", QString::number(count));
    }
    if(page>1)
    {
        params.insert("page", QString::number(page));
        url.addQueryItem("page", QString::number(page));
    }
    if(baseApp==1)
    {
        params.insert("base_app", QString::number(baseApp));
        url.addQueryItem("base_app", QString::number(baseApp));
    }
    if(feature>0&&feature<5)
    {
        params.insert("feature", QString::number(feature));
        url.addQueryItem("feature", QString::number(feature));
    }
    QNetworkRequest request;
    request.setUrl(url);
    this->setOAuthAuthorize( request, OAuth::GET, servicesInstance->getServices("MyTimeline"), params);
    Http *http = new Http(this);
    QString content = http->get(request);
    if(http->hasNetworkError())
    {
        qDebug("%d", http->getNetworkErrorCode());
        return NULL;
    }
    delete http;
    qDebug("error code is %d", http->getNetworkErrorCode());
    return content;
}

QString SinaWeibo::userWeiboPageStatusToHtml(const QList<Status> &statusList, 
                                             const QMap<QString, Status> &retwStatusMap)
{
    
    QString zfwb = "转发微博";
    QByteArray zfwbba = zfwb.toAscii().toBase64();
    /*
     %1--------------id
     %2--------------userinfo html
     %3--------------username
     %4--------------tool html
     %5--------------text
     %6--------------ret or picture html
     */
    QString statusHtml="<li><div id=%1><div class=userinfo>%2</div>"
                       "<div class=weibocontent>%3<div name=%1_tool class=tool>%4</div><p>%5</p>"
                       "<div name=%1_commentArea class=commentArea></div>%6<p>%7</p></div>"
                       "<div class=clear></div></div></li>";
    /*
     1------------retwStatus username
     2------------retwTool html
     3------------retwStatus text
     4------------picture html
     5------------retwStatus id
     */
    QString retwHtml="<div class=retw>%1<div name=%5_tool class=tool>%2</div><p>%3</p>"
                     "<div name=%5_commentArea class=commentArea></div>%4</div>";
    QString tmp;
    if(statusList.isEmpty())
        return tr("没有更多微博了!");
    for(int i=0; i<statusList.length(); i++)
    {
        Status status = statusList.at(i);
        QString userinfoHtml="<img width=50 height=50 src="+status.getUserProfileImageUrl()+"></img>";
        QString toolHtml="<a name="+status.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+status.getId()+"\",\""+
                         zfwbba+"\""+ ")>转发</a>"
                         "|<a title=收藏 href=javascript:void(0) onclic=addFavorite("+status.getId()+")>收藏</a>"
                        "|<a title=评论 href=javascript:void(0) onclick=comment("+status.getId()+")>评论</a>";
        if(status.getUserId()==account->getId())
            toolHtml.prepend("<a title=删除 href=javascript:void(0) onclick=deleteStatus("+status.getId()+
                            ")>删除</a>|");
        QString retwOrPic;
        if(!status.getRetweetedId().isEmpty())
        {
            QString aText = "//@"+status.getUserName()+":"+status.getText();
            if(account->getId()!=status.getUserId())
                toolHtml="<a name="+status.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+status.getId()+"\",\""+
                         aText.toAscii().toBase64()+ "\")>转发</a>"
                         "|<a title=收藏 href=javascript:void(0) onclick=addFavorite("+status.getId()+")>收藏</a>"
                         "|<a title=评论 href=javascript:void(0) onclick=comment("+status.getId()+")>评论</a>";
            else
                toolHtml="<a title=删除 href=javascript:void(0) onclick=deleteStatus("+status.getId()+")>删除</a>"
                        "|<a name="+status.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+status.getId()+"\",\""+
                         aText.toAscii().toBase64()+ "\")>转发</a>"
                         "|<a title=收藏 href=javascript:void(0) onclick=addFavorite("+status.getId()+")>收藏</a>"
                         "|<a title=评论 href=javascript:void(0) onclick=comment("+status.getId()+")>评论</a>";
            Status retwStatus = retwStatusMap.value(status.getRetweetedId());
            QString retwToolHtml = "<a name="+retwStatus.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+
                                   retwStatus.getId()+"\",\""+zfwbba+"\""+ ")>转发</a>"
                          "|<a title=收藏 href=javascript:void(0) onclick=addFavorite("+retwStatus.getId()+")>收藏</a>"
                          "|<a title=评论 href=javascript:void(0) onclick=comment("+retwStatus.getId()+")>评论</a>";
            if(!retwStatus.getThumbnailPic().isEmpty())
                retwOrPic = retwHtml
                            .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+retwStatus.getUserName()+"\",1)>"+
                                 retwStatus.getUserName()+"</a>:")
                            .arg(retwToolHtml)
                            .arg(statusTextFormat(retwStatus.getText()))
                            .arg("<p><img title=点击查看大图 onclick=bigPicture(\""+retwStatus.getOriginalPic()+"\",\""+
                                 retwStatus.getBmiddlePic()+"\") src="+
                                 retwStatus.getThumbnailPic()+" /></p>")
                            .arg(retwStatus.getId());
            else
                retwOrPic = retwHtml
                            .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+retwStatus.getUserName()+"\",1)>"+
                                 retwStatus.getUserName()+"</a>:")
                            .arg(retwToolHtml)
                            .arg(statusTextFormat(retwStatus.getText()))
                            .arg("")
                            .arg(retwStatus.getId());
            //qDebug(toolHtml.toAscii());
        }
        else if(!status.getThumbnailPic().isEmpty())
        {
            retwOrPic = "<p><img title=点击查看大图 onclick=bigPicture(\""+status.getOriginalPic()+"\",\""+status.getBmiddlePic()+
                        "\") src="+status.getThumbnailPic()+"/></p>";
        }
        else
        {
            retwOrPic = "";
        }
        tmp.append(statusHtml
                   .arg(status.getId())
                   .arg(userinfoHtml)
                   .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+status.getUserName()+"\",1)>"+
                        status.getUserName()+"</a>:")
                   .arg(toolHtml)
                   .arg(statusTextFormat(status.getText()))
                   .arg(retwOrPic)
                   .arg(timeFormatHtml(status.getCreatedAt()))
                   );
    }
    //qDebug(tmp.toAscii());
    return contentFrame.arg(tmp);
}

/*! \brief 获取当前登录用户及其所关注用户的最新微博消息
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/friends_timeline
 * \return 成功返回微博列表(xml),反之返回QString::null
 */
QString SinaWeibo::getFriendsTimeline( qint64 sinceId, qint64 maxId, int count, int page, int baseApp, int feature)
{
    QUrl url;
    QMap<QString, QString> params;
    QString urlString(servicesInstance->getServices("FriendsTimeline"));
    url.setUrl(urlString);
    if(sinceId>0)
    {
        params.insert("since_id", QString::number(sinceId));
        url.addQueryItem("since_id", QString::number(sinceId));
    }
    if(maxId>0)
    {
        params.insert("max_id", QString::number(maxId));
        url.addQueryItem("max_id", QString::number(maxId));
    }
    if(count!=20)
        if(count>0)
        {
            params.insert("count", QString::number(count));
            url.addQueryItem("count", QString::number(count));
        }
    if(page>1)
    {
        params.insert("page", QString::number(page));
        url.addQueryItem("page", QString::number(page));
    }
    if(baseApp==1)
    {
        params.insert("base_app", QString::number(baseApp));
        url.addQueryItem("base_app", QString::number(baseApp));
    }
    if(feature>0&&feature<5)
    {
        params.insert("feature", QString::number(baseApp));
        url.addQueryItem("feature", QString::number(baseApp));
    }
    
    QNetworkRequest request;
    request.setUrl(url);
    this->setOAuthAuthorize( request, OAuth::GET, servicesInstance->getServices("FriendsTimeline"), params);
    Http *http = new Http(this);
    QString content = http->get(request);
    if(http->hasNetworkError())
    {
        return QString::null;
    }
    delete http;
    return content; 
}

QString SinaWeibo::homePageStatusToHtml(const QList<Status> &statusList, 
                                        const QMap<QString, Status> &retwStatusMap)
{
    QString zfwb = "转发微博";
    QByteArray zfwbba = zfwb.toAscii().toBase64();
    /*
     %1--------------userinfo html
     %2--------------username
     %3---------------status id
     %4--------------tool html
     %5--------------text
     %6--------------ret or picture html
     %7--------------time or more
     */
    QString statusHtml="<li><div class=userinfo>%1</div>"
                       "<div class=weibocontent>%2<div name=%3_tool class=tool>%4</div>"
                       "<p>%5</p><div name=%3_commentArea class=commentArea></div>%6<p>%7</p></div>"
                       "<div class=clear></div></li>";
    /*
     1------------retwStatus username
     2------------retwStatus id
     3------------retwTool html
     4------------retwStatus text
     5------------picture html
     */
    QString retwHtml="<div class=retw>%1<div name=%2_tool class=tool>%3</div><p>%4</p>"
                     "<div name=%2_commentArea class=commentArea></div>%5</div>";
    QString tmp;
    if(statusList.isEmpty())
        return tr("没有更多微博了!");
    for(int i=0; i<statusList.length(); i++)
    {
        Status status = statusList.at(i);
        QString userinfoHtml="<img width=50 height=50 src="+status.getUserProfileImageUrl()+"></img>";
        QString toolHtml="<a name="+status.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+status.getId()+"\",\""+
                         zfwbba+"\""+ ")>转发</a>"
                         "|<a title=收藏 href=javascript:void(0) onclick=addFavorite("+status.getId()+")>收藏</a>"
                         "|<a title=评论 href=javascript:void(0) onclick=comment("+status.getId()+")>评论</a>";
        QString retwOrPic;
        if(!status.getRetweetedId().isEmpty())
        {
            QString aText = "//@"+status.getUserName()+":"+status.getText();
            toolHtml="<a name="+status.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+status.getId()+"\",\""+
                     aText.toAscii().toBase64()+ "\")>转发</a>"
                     "|<a title=收藏 href=javascript:void(0) onclick=addFavorite("+status.getId()+")>收藏</a>"
                     "|<a title=评论 href=javascript:void(0) onclick=comment("+status.getId()+")>评论</a>";
            Status retwStatus = retwStatusMap.value(status.getRetweetedId());
            QString retwToolHtml = "<a name="+retwStatus.getId()+"_retw title=转发 href=javascript:void(0) onclick=retw(\""+
                                   retwStatus.getId()+"\",\""+zfwbba+"\""+ ")>转发</a>"
                          "|<a title=收藏 href=javascript:void(0) onclick=addFavorite("+retwStatus.getId()+")>收藏</a>"
                          "|<a title=评论 href=javascript:void(0) onclick=comment("+retwStatus.getId()+")>评论</a>";
            if(!retwStatus.getThumbnailPic().isEmpty())
                retwOrPic = retwHtml
                            .arg("<a href=javascript:void(0) title="+retwStatus.getUserName()+" onclick=getUserTimeline(\""+
                                 retwStatus.getUserName()+"\",1)>"
                                 +retwStatus.getUserName()+"</a>:")
                            .arg(retwStatus.getId())
                            .arg(retwToolHtml)
                            .arg(this->statusTextFormat(retwStatus.getText()))
                            .arg("<p><img title=点击查看大图 onclick=bigPicture(\""+retwStatus.getOriginalPic()+"\",\""+
                                 retwStatus.getBmiddlePic()+"\") src="+
                                 retwStatus.getThumbnailPic()+" /></p>");
            else
                retwOrPic = retwHtml
                            .arg("<a href=javascript:void(0) title="+retwStatus.getUserName()+
                                 " onclick=getUserTimeline(\""+retwStatus.getUserName()+"\",1)>"
                                 +retwStatus.getUserName()+"</a>:")
                            .arg(retwStatus.getId())
                            .arg(retwToolHtml)
                            .arg(this->statusTextFormat(retwStatus.getText()))
                            .arg("");
            //qDebug(toolHtml.toAscii());
        }
        else if(!status.getThumbnailPic().isEmpty())
        {
            retwOrPic = "<p><img title=点击查看大图 onclick=bigPicture(\""+
                        status.getOriginalPic()+"\",\""+status.getBmiddlePic()+"\") src="
                        +status.getThumbnailPic()+"/></p>";
        }
        else
        {
            retwOrPic = "";
        }
        tmp.append(statusHtml
                   .arg(userinfoHtml)
                   .arg("<a href=javascript:void(0) title="+status.getUserName()+
                        " onclick=getUserTimeline(\""+status.getUserName()+"\",1)>"
                        +status.getUserName()+"</a>:")
                   .arg(status.getId())
                   .arg(toolHtml)
                   .arg(this->statusTextFormat(status.getText()))
                   .arg(retwOrPic)
                   .arg(timeFormatHtml(status.getCreatedAt()))
                   );
    }
    //qDebug(tmp.toAscii());
    return contentFrame.arg(tmp);
}

/*! \brief 返回最新n条发送及收到的评论
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/comments_timeline
 * \return 收到的评论列表(xml)，反之返回QString::null
 */
QString SinaWeibo::getCommentTimeline(qint64 sinceId, qint64 maxId, int count, int page)
{
    QUrl url;
    QMap<QString, QString> params;
    QString urlString(servicesInstance->getServices("CommentsTimeline"));
    url.setUrl(urlString);
    if(sinceId>0)
    {
        params.insert("since_id", QString::number(sinceId));
        url.addQueryItem("since_id", QString::number(sinceId));
    }
    if(maxId>0)
    {
        params.insert("max_id", QString::number(maxId));
        url.addQueryItem("max_id", QString::number(maxId));
    }
    if(count!=20)
        if(count>0)
        {
            params.insert("count", QString::number(count));
            url.addQueryItem("count", QString::number(count));
        }
    if(page>1)
    {
        params.insert("page", QString::number(page));
        url.addQueryItem("page", QString::number(page));
    }
    QNetworkRequest request;
    request.setUrl(url);
    this->setOAuthAuthorize( request, OAuth::GET, servicesInstance->getServices("CommentsTimeline"), params);
    Http *http = new Http(this);
    QString content = http->get(request);
    if(http->hasNetworkError())
    {
        return QString::null;
    }
    delete http;
     return content; 
}

QString SinaWeibo::commentPageStatusToHtml(const QList<Status> &statusList, 
                                           const QMap<QString, Status> &retwStatusMap)
{
    /*
        %1------userinfo html
        %2------username
        %3------tool html
        %4------status Text
        %5------retw or pic html
        %6
     */
    QString commentMeHtml="<li><div class=userinfo>%1</div>"
                     "<div class=weibocontent>%2<div class=tool>%3</div>"
                     "<p>%4</p>%5<p>%6</p></div><div class=clear></div></li>";
    /*
        %1------ret username
        %2------status text
        %3------picture
     */
    QString retwHtml="<div class=retw>%1<div class=tool></div><p>%2</p>%3</div>";
    QString tmp;
    QString userinfoHtml ;
    QString toolHtml="";
    if(statusList.isEmpty())
        return tr("没有更多评论了!");
    for(int i=0; i<statusList.length(); i++)
    {
        Status status = statusList.at(i);
        userinfoHtml = "<img width=50 height=50 src="+status.getUserProfileImageUrl()+"\"></img>";
        
        QString retwOrPic;
        if(!status.getRetweetedId().isEmpty())
        {
            Status retwStatus = retwStatusMap.value(status.getRetweetedId());
            toolHtml = "<a href=javascript:void(0) onclick=replyComment(\""+status.getId()+"\",\""+
                       retwStatus.getId()+"\")>回复</a>";
            if(!retwStatus.getThumbnailPic().isEmpty())
                retwOrPic = retwHtml
                            .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+retwStatus.getUserName()+"\",1)>"+
                                 retwStatus.getUserName()+"</a>:")
                            .arg(statusTextFormat(retwStatus.getText()))
                            .arg("<p><img title=点击查看大图 onclick=bigPicture(\""+retwStatus.getOriginalPic()+"\",\""+
                                 retwStatus.getBmiddlePic()+"\") src="+
                                 retwStatus.getThumbnailPic()+" /></p>");
            else
                retwOrPic = retwHtml
                            .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+retwStatus.getUserName()+"\",1)>"+
                                 retwStatus.getUserName()+"</a>:")
                            .arg(statusTextFormat(retwStatus.getText()))
                            .arg("");
        }
        else if(!status.getThumbnailPic().isEmpty())
        {
            retwOrPic = "<p><img title=点击查看大图 onclick=bigPicture(\""+status.getOriginalPic()+"\",\""+status.getBmiddlePic()
                        +"\") src="+status.getThumbnailPic()+"/></p>";
        }
        else
        {
            retwOrPic = "";
        }
        tmp.append(commentMeHtml
                   .arg(userinfoHtml)
                   .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+status.getUserName()+"\",1)>"+
                        status.getUserName()+"</a>:")
                   .arg(toolHtml)
                   .arg(statusTextFormat(status.getText()))
                   .arg(retwOrPic)
                   .arg(timeFormatHtml(status.getCreatedAt())));
    }
    return contentFrame.arg(tmp);
}

QString SinaWeibo::directMessagePageStatusToHtml(const QList<Status> &statusList)
{
    /*
        %1------userinfo html
        %2------username
        %3------tool html
        %4------status Text
        %5-------datetime
     */
    QString directMessageHtml="<li><div class=userinfo>%1</div>"
                     "<div class=weibocontent>%2<div class=tool>%3</div>"
                     "<p>%4</p><p>%5</p></div><div class=clear></div></li>";
    if(statusList.isEmpty())
        return "没有收藏哦!";
    QString result;
    QString userinfoHtml = "<img width=50 height=50 src=%1></img>";
    QString usernameHtml = "<a href=javascript:void(0) onclick=getUserTimeline(\"%1\",1)>%2</a>";
    QString toolHtml = "<a href=javascript:void(0) onclick=sendDirectMessage(\"%1\")>回复</a>";
    for( int i=0; i<statusList.length(); i++)
    {
        Status status = statusList.at(i);
        result.append(directMessageHtml
                      .arg(userinfoHtml.arg(status.getUserProfileImageUrl()))
                      .arg(usernameHtml.arg(status.getUserName()).arg(status.getUserName()))
                      .arg(toolHtml.arg(status.getUserId()))
                      .arg(statusTextFormat(status.getText()))
                      .arg(timeFormatHtml(status.getCreatedAt()))
                      );
    }
    return contentFrame.arg(result);
}

QString SinaWeibo::commentsListToHtml(const QList<Status> &statusList)
{
    /*
     1----------userinfo html
     2----------username html
     3----------tool html
     4----------status text
     5----------time html
     */
    QString commentsHtml="<li><div class=minicomments><div class=miniuserinfo>%1</div>"
                         "<div class=miniweibocontent>%2<div class=minitool>%3</div><p>%4</p>%5</div>"
                         "<div style=\"font: 0px/0px sans-serif;clear: both;display: block\"> </div></div></li>";
    QString tmp;
    for( int i=0; i<statusList.length(); i++)
    {
        Status status = statusList.at(i);
        tmp.append( commentsHtml
                    .arg("<img height=30 width=30 src="+status.getUserProfileImageUrl()+" />")
                    .arg("<a href=javascript:void(0) onclick=getUserTimeline(\""+status.getUserName()+"\",1)>"+
                                                                              status.getUserName()+"</a>:")
                    .arg("<a href=javascript:void(0) onclick=replyComment(\""+status.getId()+"\",\""+status.getRetweetedId()
                         +"\")>回复</a>")
                    .arg(statusTextFormat(status.getText()))
                    .arg(this->timeFormatHtml(status.getCreatedAt()))
                );
    }
    tmp.prepend("<hr><ul>");
    tmp.append("</ul>");
    //qDebug(tmp.toAscii());
    return tmp;
}

QString SinaWeibo::statusToHtmlForNotifier(Status &status)
{
    QString html = "%1:\n%2";
//    if(!status.getBmiddlePic().isEmpty())
//        html.append("<a style=color:red >[图]</a>");
    return html.arg(status.getUserName()).arg(status.getText());
}

QString SinaWeibo::statusToHtmlForNotifier(Status &status, Status &retwStatus)
{
    QString html = "%1:\n%2\n"
                   "%3:\n%4";
//    if(!retwStatus.getBmiddlePic().isEmpty())
//        html.append("<a style=color:red>[图]</a>");
    return html
            .arg(status.getUserName())
            .arg(status.getText())
            .arg(retwStatus.getUserName())
            .arg(retwStatus.getText());
}

/*! \brief 登录用户的最新收到的n条私信
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Direct_messages
 *
 * \return 私信列表(xml),反之返回QString::null
 */
QString SinaWeibo::getDirectMessage(qint64 sinceId, qint64 maxId, int count, int page)
{
    QString urlString(servicesInstance->getServices("DirectMessages"));
    QUrl url(urlString);
    QMap<QString, QString> params;
    if(sinceId>0)
    {
        params.insert("since_id", QString::number(sinceId));
        url.addQueryItem("since_id", QString::number(sinceId));
    }
    if(maxId>0)
    {
        params.insert("max_id", QString::number(maxId));
        url.addQueryItem("max_id", QString::number(maxId));
    }
    if(count!=20&&count>0)
    {
        params.insert("count", QString::number(count));
        url.addQueryItem("count", QString::number(count));
    }
    if(page>1)
    {
        params.insert("page", QString::number(page));
        url.addQueryItem("page", QString::number(page));
    }
    QNetworkRequest request(url);
    this->setOAuthAuthorize( request, OAuth::GET, servicesInstance->getServices("DirectMessages"), params);
    Http *http = new Http(this);
    QString content = http->get(request);
    if(http->hasNetworkError())
    {
        delete http;
        return NULL;
    }
    delete http;
    return content;
}

/*! \brief Http Basic 认证
 *
 * \warning 已废弃开始采用OAuth认证
 */
void SinaWeibo::setBasicAuth(QNetworkRequest &request)
{
    request.setRawHeader("Authorization", this->basicAuthInfo.toAscii());
}

/*! \brief 获取用户头像
 *
 */
QIcon SinaWeibo::getProfileIcon(const QString &urlString)
{
    QUrl iconUrl;
    iconUrl.setUrl(urlString);
    QNetworkRequest request;
    request.setUrl(iconUrl);
    Http *http = new Http(this);
    QPixmap image = http->getImageFromUrl(request);
    delete http;
    QIcon icon(image);
    return icon;
}
/*! \brief 返回新浪微博官方所有表情
 *
 *  API详情: http://open.t.sina.com.cn/wiki/index.php/Emotions
 *  \return 表情列表(xml),反之返回QString::null
 */
QString SinaWeibo::getEmotions()
{
    QUrl url(servicesInstance->getServices("Emotions")+"?source="+servicesInstance->getServices("Source"));
    QNetworkRequest request;
    request.setUrl(url);
    Http *http = new Http(this);
    QString content = http->get(request);
    delete http;
    return content;
}

/*! \brief 获取当前用户Web主站未读消息数
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/unread
 * \return 成功返回xml格式列表，否则返回QString::null
 */
QString SinaWeibo::getUnread(QString sinceId)
{
    QString urlString = servicesInstance->getServices("Unread");
    QUrl url(urlString);
    QMap<QString, QString> params;
    if(!sinceId.isEmpty())
    {
        params.insert("with_new_status", QString::number(1));
        url.addQueryItem("with_new_status", QString::number(1));
        params.insert("since_id", sinceId);
        url.addQueryItem("since_id", sinceId);
    }
    QNetworkRequest request;
    request.setUrl(url);
    this->setOAuthAuthorize( request, OAuth::GET, urlString, params);
    Http *http = new Http(this);
    QString content = http->get(request);
    if(http->hasNetworkError())
        return QString::null;
    delete http;
    qDebug(content.toAscii());
    return content;
}

/*! \brief 批量获取一组微博的评论数及转发数
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/counts
 *
 * \return 成功时返回评论数和转发数(json),反之返回QStirng::null
 */
QString SinaWeibo::getStatusCountsByJson(QList<Status> &statusList)
{
    QStringList idStrings;
    for( int i=0; i<statusList.length(); i++)
    {
        Status status = statusList.at(i);
        idStrings.append(status.getId());
        if(!status.getRetweetedId().isEmpty())
        {
            idStrings.append(status.getRetweetedId());
        }
    }
    if(idStrings.isEmpty())
        return QString::null;
    QMap<QString, QString> params;
    QString urlString(servicesInstance->getServices("Counts"));
    QUrl url(urlString);
    params.insert("ids", idStrings.join(",").toAscii().toPercentEncoding());
    url.addQueryItem("ids", idStrings.join(","));
    QNetworkRequest request(url);
    this->setOAuthAuthorize( request, OAuth::GET, urlString, params);
    Http *http = new Http(this);
    QString content = http->get(request);
    if(http->hasNetworkError())
    {
        qDebug("error code %d", http->getNetworkErrorCode());
        delete http;
        return QString::null;
    }
    delete http;
    return content;
}

/*! \brief 表情列表初始化
 *
 */
void SinaWeibo::initEmotions()
{
    //get emotions xml file
    Configuration *conf = Configuration::getInstance();
    QString emotionXml;
    QFile file(conf->getProfilesDir()+"/emotions.xml");
    if(!file.exists())
    {
        emotionXml = getEmotions();
        if(file.open(QIODevice::WriteOnly))
        {
            QTextStream out(&file);
            out<<emotionXml;
        }
    }
    else
    {
       if( file.open(QIODevice::ReadOnly))
           emotionXml.append(file.readAll());
       else
           emotionXml = getEmotions();
                
    }
    file.close();
    if(!emotionXml.isEmpty())
    {
        SinaServices *sina = SinaServices::getInstance();
        sina->emoticonMap.clear();
        sina->emotionCategoryList.clear();
        sina->emotionList.clear();
        QList<Emotion> &emotionList=sina->emotionList;
        SinaParserXml sinaPX;
        sinaPX.parserEmotions(emotionXml,emotionList);//got the emotion list
        for( int i=0; i<emotionList.length(); i++)
        {
            Emotion emotion = emotionList.at(i);
            sina->emoticonMap.insert(emotion.getPhrase(), emotion.getUrl());
            sina->addToEmotionCategoryList(emotion.getCategory());
        }
    }
}

/*! \brief 发布一条微博信息
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/update
 * \return 成功时返回QNetworkReply::NoError, 反之返回错误代码
 */
int SinaWeibo::sendStatusWithoutPicture(QString statusContent)
{
    QMap<QString, QString> params;
    params.insert("status", QUrl::toPercentEncoding(statusContent));
    QByteArray data = "status="+QUrl::toPercentEncoding(statusContent.toUtf8());
    QString urlString = servicesInstance->getServices("Update");
    QNetworkRequest request(QUrl::fromUserInput(urlString));
    this->setOAuthAuthorize( request, OAuth::POST, urlString, params);
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                         "application/x-www-form-urlencoded");
    request.setHeader(QNetworkRequest::ContentLengthHeader, 
                         QByteArray::number(data.length()));
    Http *http = new Http(this);
    http->post(request, data);
    if(http->hasNetworkError())
    {
        return http->getNetworkErrorCode();
    }
    delete http;
    return QNetworkReply::NoError;
}

/*! \brief 将当前登录用户的某种新消息的未读数设置为0
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/reset_count
 * \return 成功返回QNetworkReply::NoError,反之返回相应错误码
 */
int SinaWeibo::resetCount(int type)
{
    if(type<1||type>4)
        return QNetworkReply::NoError;//no error -_-!!!
    QMap<QString, QString> params;
    params.insert("type", QString::number(type));
    QString dataString =  "type="+QString::number(type);
    QNetworkRequest request(QUrl::fromUserInput(servicesInstance->getServices("ResetCount")));
    this->setOAuthAuthorize( request, OAuth::POST, servicesInstance->getServices("ResetCount"), params);
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                         "application/x-www-form-urlencoded");
    request.setHeader(QNetworkRequest::ContentLengthHeader, 
                         QByteArray::number(dataString.toAscii().length()));
    Http *http = new Http(this);
    http->post(request, dataString.toAscii());
    if(http->hasNetworkError())
        return http->getNetworkErrorCode();
    delete http;
    return QNetworkReply::NoError;
}

/*! \brief 转发微博
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/repost
 * \return 成功返回QNetworkReply::NoError,反之返回相应错误码
 */
int SinaWeibo::repost(QString id, QString status)
{
    QMap<QString, QString> params;
    params.insert("id", id);
    params.insert("status", QUrl::toPercentEncoding(status));
    QByteArray data = "id=" + id.toAscii() + "&status=" + QUrl::toPercentEncoding(status.toUtf8());
    QString urlString = servicesInstance->getServices("Repost");
    QNetworkRequest request(QUrl::fromUserInput(urlString));
    this->setOAuthAuthorize( request, OAuth::POST, urlString, params);
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                      "application/x-www-form-urlencoded");
    request.setHeader(QNetworkRequest::ContentLengthHeader,
                      QByteArray::number(data.length()));
    Http *http = new Http(this);
    http->post(request, data);
    if(http->hasNetworkError())
    {
        return http->getNetworkErrorCode();
    }
    delete http;
    return QNetworkReply::NoError;
}

/*! \brief 对一条微博信息进行评论
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/comment
 * \return 成功返回QNetworkReply::NoError,反之返回相应错误码
 */
int SinaWeibo::commentStatus(QString id, QString status)
{
    QMap<QString, QString> params;
    QByteArray data = "id="+ id.toAscii()+"&comment=" + QUrl::toPercentEncoding(status.toUtf8());
    params.insert("id", id);
    params.insert("comment", QUrl::toPercentEncoding(status));
    QString urlString = servicesInstance->getServices("Comment");
    QNetworkRequest request(QUrl::fromUserInput(urlString));
    this->setOAuthAuthorize( request, OAuth::POST, urlString, params);
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                      "application/x-www-form-urlencoded");
    request.setHeader(QNetworkRequest::ContentLengthHeader,
                      QByteArray::number(data.length()));
    Http *http = new Http(this);
    http->post(request, data);
    if(http->hasNetworkError())
    {
        return http->getNetworkErrorCode();
    }
    delete http;
    return QNetworkReply::NoError;
}

/*! \brief 回复评论
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/reply
 * \return 成功返回QNetworkReply::NoError,反之返回相应错误码
 */
int SinaWeibo::replyComment(QString cid, QString id, QString statusText)
{
    QByteArray data = "id="+ id.toAscii() + "&cid="+ cid.toAscii()+
                      "&comment=" + QUrl::toPercentEncoding(statusText.toUtf8());
    QMap<QString, QString> params;
    params.insert("id", id);
    params.insert("cid", cid);
    params.insert("comment", QUrl::toPercentEncoding(statusText));
    QString urlString = servicesInstance->getServices("CommentReply");
    QNetworkRequest request(QUrl::fromUserInput(urlString));
    this->setOAuthAuthorize( request, OAuth::POST, urlString, params);
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                      "application/x-www-form-urlencoded");
    request.setHeader(QNetworkRequest::ContentLengthHeader,
                      QByteArray::number(data.length()));
    Http *http = new Http(this);
    http->post(request, data);
    if(http->hasNetworkError())
    {
        delete http;
        return http->getNetworkErrorCode();
    }
    delete http;
    return QNetworkReply::NoError;
}

/*! \brief 发送私信
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Direct_messages/new
 * \warning 私信的接收方必须是发送方的粉丝(什么破限制)
 * \return 成功返回QNetworkReply::NoError,反之返回相应错误码
 */
int SinaWeibo::sendDirectMessage(QString uid, QString statusText)
{
    QByteArray data = "id="+ uid.toAscii()+ "&text=" + QUrl::toPercentEncoding(statusText.toUtf8());
    QMap<QString, QString> params;
    params.insert("id", uid);
    params.insert("text", QUrl::toPercentEncoding(statusText));
    QString urlString = servicesInstance->getServices("SendDirectMessage");
    QNetworkRequest request(QUrl::fromUserInput(urlString));
    this->setOAuthAuthorize( request, OAuth::POST, urlString, params);
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                      "application/x-www-form-urlencoded");
    request.setHeader(QNetworkRequest::ContentLengthHeader,
                      QByteArray::number(data.length()));
    Http *http = new Http(this);
    http->post(request, data);
    if(http->hasNetworkError())
    {
        delete http;
        return http->getNetworkErrorCode();
    }
    delete http;
    return QNetworkReply::NoError;
}

void SinaWeibo::getUnreadInfo(int &statusUnread, int &atMeMentionsUnread, 
                              int &commentsUnread, int &directMessageUnread, int &newFollower)
{
    QString xmlContent;
    if(!account->homePageStatus.isEmpty())
    {
        Status status = account->homePageStatus.at(0);
        xmlContent = getUnread(status.getId());
    }
    else
    {
        xmlContent = getUnread("");
    }
    //qDebug(xmlContent.toAscii());
    if(xmlContent.isEmpty())
    {
        statusUnread += 0;
        atMeMentionsUnread += 0;
        commentsUnread += 0;
        directMessageUnread += 0;
        newFollower += 0;
        return;
    }
    SinaParserXml sinaParserXml;
    sinaParserXml.parserUnreadXml(xmlContent, statusUnread, atMeMentionsUnread, commentsUnread, 
                                  directMessageUnread, newFollower);
}

/*! \brief 添加收藏
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Favorites/create
 * \return 成功返回QNetworkReply::NoError,反之返回相应错误码
 */
int SinaWeibo::addFavorite(QString id)
{
    QByteArray data = "id="+id.toAscii();
    QMap<QString, QString> params;
    params.insert("id", id);
    QString urlString = servicesInstance->getServices("AddFavorite");
    QNetworkRequest request(QUrl::fromUserInput(urlString));
    this->setOAuthAuthorize( request, OAuth::POST, urlString, params);
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                      "application/x-www-form-urlencoded");
    request.setHeader(QNetworkRequest::ContentLengthHeader,
                      QByteArray::number(data.length()));
    Http *http = new Http(this);
    http->post(request, data);
    if(http->hasNetworkError())
    {
        return http->getNetworkErrorCode();
    }
    delete http;
    return QNetworkReply::NoError;
}

/*! \brief 删除收藏
 *
 * API详情:  http://open.t.sina.com.cn/wiki/index.php/Favorites/destroy
 * \return 成功返回QNetworkReply::NoError,反之返回相应错误码
 */
int SinaWeibo::deleteFavorite(QString id)
{
    QMap<QString, QString> params;
    QByteArray data;
    QString urlString = servicesInstance->getServices("DeleteFavorite").arg(id);
    QNetworkRequest request(QUrl::fromUserInput(urlString));
    this->setOAuthAuthorize( request, OAuth::POST, urlString, params);
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                      "application/x-www-form-urlencoded");
    request.setHeader(QNetworkRequest::ContentLengthHeader,
                      QByteArray::number(data.length()));
    Http *http = new Http(this);
    http->post(request, data);
    if(http->hasNetworkError())
    {
        return http->getNetworkErrorCode();
    }
    delete http;
    return QNetworkReply::NoError;
}

/*! \brief 删除微博
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/destroy 
 * 
 * \return 成功返回QNetworkReply::NoError,反之返回相应错误码
 */
int SinaWeibo::deleteStatus(QString id)
{
    QByteArray data;
    QMap<QString, QString> params;
    QString urlString = servicesInstance->getServices("DeleteStatus").arg(id);
    QNetworkRequest request(QUrl::fromUserInput(urlString));
    this->setOAuthAuthorize( request, OAuth::POST, urlString, params);
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                      "application/x-www-form-urlencoded");
    request.setHeader(QNetworkRequest::ContentLengthHeader,
                      QByteArray::number(data.length()));
    Http *http = new Http(this);
    http->post(request, data);
    if(http->hasNetworkError())
    {
        return http->getNetworkErrorCode();
    }
    delete http;
    return QNetworkReply::NoError;
}

/*! \brief 发表微博并上传图片
 *
 * API详情: http://open.t.sina.com.cn/wiki/index.php/Statuses/upload
 * \return 成功返回QNetworkReply::NoError,反之返回相应错误码
 */
int SinaWeibo::sendStatusWithPicture(QString statusContent, QByteArray pictureInByteArray, QString fileName)
{
    QString boundary = "---------------------------723690991551375881941828858";

    QByteArray data(QString("--" + boundary + "\r\n").toAscii());
    //statusContent
    data += "Content-Disposition: form-data; name=\"status\"\r\n\r\n";
    data += QUrl::toPercentEncoding(statusContent.toUtf8());
    data += "\r\n";
    //pic
    data += QString("--" + boundary + "\r\n").toAscii();
    data += "Content-Disposition: form-data; name=\"pic\"; filename=\""+fileName.toUtf8()+"\"\r\n";
    data += "Content-Type: image/jpeg\r\n\r\n";
    data += pictureInByteArray;
    data += "\r\n";
    data += QString("--" + boundary + "--\r\n").toAscii();
    //end of data
    
    QMap<QString, QString> params;
    params.insert("status", QUrl::toPercentEncoding(QUrl::toPercentEncoding(statusContent)));
    
    QNetworkRequest request(QUrl::fromUserInput(servicesInstance->getServices("Upload")));
    this->setOAuthAuthorize( request, OAuth::POST, servicesInstance->getServices("Upload"), params);
    request.setHeader(QNetworkRequest::ContentTypeHeader,
                      "multipart/form-data; boundary=" + boundary);
    Http *http = new Http(this);
    http->post(request, data);
    if(http->hasNetworkError())
        return http->getNetworkErrorCode();
    delete http;
    return QNetworkReply::NoError;
}

void SinaWeibo::initHomePageStatus()
{
    QString xmlContent = getFriendsTimeline(0, 0, conf->getAccountConf(account->getId(),conf->homeCS), 1, 0, 0);
    account->RemoveAll(account->homePageStatus, account->homePageRetweeted);
    SinaParserXml sinaParserXml;
    sinaParserXml.parserStatusXml(xmlContent, account->homePageStatus, account->homePageRetweeted);
}

void SinaWeibo::initUserWeiboPageStatus()
{
    QString xmlContent = getUserTimeline(0,conf->getAccountConf(account->getId(),conf->userWeiboCS),1,0,0);
    account->RemoveAll(account->userWeiboPageStatus, account->userWeiboPageRetweeted);
    SinaParserXml sinaParserXml;
    sinaParserXml.parserStatusXml(xmlContent, account->userWeiboPageStatus, account->userWeiboPageRetweeted);
}

void SinaWeibo::initAtMePageStatus()
{
    QString xmlContent = getMentions(0, 0, conf->getAccountConf(account->getId(), conf->atMeCS), 1);
    account->RemoveAll(account->atMePageStatus, account->atMePageRetweeted);
    SinaParserXml sinaParserXml;
    sinaParserXml.parserStatusXml(xmlContent, account->atMePageStatus, account->atMePageRetweeted);
}

void SinaWeibo::initFavoritePageStatus()
{
    QString xmlContent = getFavorites(1);
    account->RemoveAll(account->favoritesPageStatus, account->favoritesPageRetweeted);
    SinaParserXml sinaParserXml;
    sinaParserXml.parserStatusXml(xmlContent,account->favoritesPageStatus, account->favoritesPageRetweeted);
}

void SinaWeibo::initCommentPageStatus()
{
    QString xmlContent = getCommentTimeline(0, 0, conf->getAccountConf(account->getId(), conf->commentCS), 1);
    account->RemoveAll(account->commentPageComments, account->commentPageRetweeted);
    SinaParserXml sinaParserXml;
    sinaParserXml.parserCommentTimeline(xmlContent, 
                                        account->commentPageComments, account->commentPageRetweeted);
}

void SinaWeibo::initDirectMessagePageStatus()
{
    QString xmlContent = this->getDirectMessage(0,0,
                                                conf->getAccountConf(account->getId(), conf->directMessageCS), 1);
    account->RemoreAll(account->directMessagePageStatus);
    SinaParserXml sinaParserXml;
    sinaParserXml.parserDirectMessage(xmlContent, account->directMessagePageStatus);
}

QString SinaWeibo::statusTextFormat(QString statusText)
{
    QRegExp urlRE("http://([\\w-]+\\.)+[\\w-]+(/[A-Za-z0-9]*)");
    int s = -1;
    QString reText;
    SinaServices * sina = SinaServices::getInstance();
    while((s=urlRE.indexIn(statusText, s+1))>=0)
    {
        reText = "<a href=javascript:void(0) onclick=openUrl(\""+urlRE.cap(0)+"\")>"+urlRE.cap(0)+"</a>";
        statusText.replace(s, urlRE.cap(0).length(), reText);
        s += reText.length();
    }
    QRegExp emotionRE("\\[\\S+\\]");
    emotionRE.setMinimal(true);
    s = -1;
    while((s=emotionRE.indexIn(statusText, s+1))>=0)
    {
        if(!sina->emoticonMap.value(emotionRE.cap(0),"").isEmpty())
        {
            reText = "<img src="+sina->emoticonMap.value(emotionRE.cap(0))+" alt="+emotionRE.cap(0)+" title="+
                     emotionRE.cap(0)+" />";
            statusText.replace(s, emotionRE.cap(0).length(), reText);
            s+= reText.length();
        }
        else
            continue;
    }
    QRegExp trendsRE("#(.+)#");
    trendsRE.setMinimal(true);
    s = -1;
    while((s=trendsRE.indexIn(statusText, s+1))>=0)
    {
        reText="<a href=javascript:void(0) onclick=trends(\""+trendsRE.cap(1)+"\")>"+trendsRE.cap(0)+"</a>";
        statusText.replace(s, trendsRE.cap(0).length(),reText);
        s += reText.length();
    }
    QRegExp atUsername("@([A-Za-z0-9\\x4e00-\\x9fa5_-]{2,20})");
    s = -1;
    while((s=atUsername.indexIn(statusText, s+1))>=0)
    {
        reText="<a href=javascript:void(0) onclick=getUserTimelineByScreenName(\""+atUsername.cap(1)+"\",1)>"
               +atUsername.cap(0)+"</a>";
        statusText.replace(s, atUsername.cap(0).length(), reText);
        s += reText.length();
    }
    return statusText;
}

QString SinaWeibo::timeFormatHtml(QDateTime datetime)
{
    if(datetime.isValid())
    {
        QDate date = datetime.date();
        QTime time = datetime.time();
        if(date==QDate::currentDate())//today
        {
            int pastSeconds = datetime.secsTo(QDateTime::currentDateTime());
            if(pastSeconds>0&&pastSeconds<60)// 0~60s
                return "<a href=javascript:void(0) >刚刚</a>";
            else if(pastSeconds<3600)
                return "<a href=javascript:void(0) >"+QString::number((int) pastSeconds/60)+"分钟前</a>";
            else
            {
                return "<a href=javascript:void(0) >今天 "+QString::number(time.hour())+":"+
                        QString::number(time.minute())+"</a>";
            }
        }
        else
        {
            return "<a href=javascript:void(0) >"+QString::number(date.month())+"月"+QString::number(date.day())+"日 "+
                    QString::number(time.hour())+":"+QString::number(time.minute())+"</a>";
        }
    }
    return NULL;
}

/*! \brief 设置OAuth Http Authorization
 *  \param params 请求参数，不包括OAuth认证参数部分
 */
void SinaWeibo::setOAuthAuthorize(QNetworkRequest &request, OAuth::HttpMethod httpMethod, QString url, QMap<QString, QString> &params )
{
    OAuth oauth;
    QMap<QString,QString> oauthParams;
    oauthParams.insert(OAuth::oauthConsumerKeyString, servicesInstance->getServices("Source"));
    oauthParams.insert(OAuth::oauthNonceString, oauth.createNonce());
    oauthParams.insert(OAuth::oauthSignatureMethodString, "HMAC-SHA1");
    oauthParams.insert(OAuth::oauthTimestampString, oauth.createTimeStamp());
    oauthParams.insert(OAuth::oauthVersionString, "1.0");
    oauthParams.insert(OAuth::oauthTokenString, servicesInstance->getServices(SinaServices::MyAccessToken));
    
    QString key = servicesInstance->getServices("Secret")+"&"+servicesInstance->getServices(SinaServices::MyAccessTokenSecret);
    params.unite(oauthParams);
    QByteArray signature = oauth.createSignature( httpMethod, url, key, params);
    oauthParams.insert(OAuth::oauthSignatureString, signature.toPercentEncoding());
    oauth.setOAuthInfo(request, oauthParams);
}
